Q: We have a situation in which the A5 world is being corrupted
in our component, even though we make a SetComponentInstanceA5 call. The application is running
on a PowerMac 7100 in 68K mode calling a 68K component (#1), that in turn calls
another component (#2 which is fat), and which, in turn, calls yet another
(#3), which is also fat. Most of the time, the A5 world is restored properly,
but on this particular call where several things are being invoked in the fat
components (#2 & #3), when we return from these components (from #3 through
#2), the A5 world's first component (#1) is incorrect.
What are we doing wrong?
A: The two most problematic areas in a component are
a) the Open routine and b) the Thing resource definition. It is likely that the Open routine is the
culprit in your case. The development environment is another potential problem
area. If you are using Think, Metrowerks, or MPW, the different handling of A5
versus Think's A4 strategy for code resources can cause problems.
A sample component that can be compiled in both native and non-native
versions is attached. Compare this component to yours to help locate the
defect. When debugging a component, it is often helpful to compare a working
component, one function at a time, to the non working component, paying
particular attention to the areas mentioned above.
Here's the sample component:
//-
pascal ComponentResult
_CurlyOpen (Handle storage, ComponentInstance self)
{
#pragma unused (storage)
ComponentResult result = noErr;
#ifdef THINK_C
SetComponentInstanceA5 (self, *(long *) CurrentA5);
#endif THINK_C
// Can we open another instance?
if (CountComponentInstances ((Component) self) <= kMaxCurlyInstances)
{
// Set up our instance storage
CurlyPrivateGlobalsHdl globals = (CurlyPrivateGlobalsHdl)
NewHandleClear (sizeof (CurlyPrivateGlobals));
// Did we get our storage?
if (globals != nil)
{
// Keep a reference to self
(**globals).self = (Component) self;
// Set storage ref
SetComponentInstanceStorage (self, (Handle) globals);
}
else // NewHandleClear failed
{
result = MemError();
}
}
else // No more instances can be opened
{
result = -
1L; // Return anonymous error
}
return (result);
}
//
|
|